package com.ydj.app.third.ai;

import com.google.gson.reflect.TypeToken;
import com.wechat.pay.java.core.util.IOUtil;
import com.ydj.app.entity.Chat;
import com.ydj.app.protocol.dto.ForecastQaItemDto;
import com.ydj.app.third.ai.deepseek.DeepseekManager;
import com.ydj.app.third.ai.yuanqi.YuanQiChatCompletionsReq;
import com.ydj.app.third.ai.yuanqi.YuanQiManager;
import com.ydj.framework.exception.CommonException;
import com.ydj.framework.utils.JsonUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class AiModelService {

    @Autowired
    private DeepseekManager deepseekManager;
    @Autowired
    private YuanQiManager yuanQiManager;

    private String forecastPrompt;

    @PostConstruct
    public void init() throws IOException {
        try (InputStream inputStream = new ClassPathResource("prompt/ForecastPrompt.md").getInputStream()) {
            forecastPrompt = IOUtil.toString(inputStream);
        }
    }

    @Getter
    @Setter
    @Accessors(chain = true)
    public static class AiForecastResult {
        private String result;
        private Integer rate;
    }

    public AiForecastResult getForecastResultByDeepseek(List<ForecastQaItemDto> qaList) throws CommonException {
        String systemPrompt = "";
        String userPrompt = forecastPrompt
                .replace("{{question}}", ForecastQaItemDto.toQuestionPrompt(qaList))
                .replace("{{answer}}", ForecastQaItemDto.toAnswerPrompt(qaList));
        String resJson = deepseekManager.chatFetchCode(systemPrompt, userPrompt, AiModelEnum.DeepseekV3.getModelName(), 0.0, "json");
        log.info("【AI 预测结果】请求:" + userPrompt + ", 返回:" + resJson);

        AiForecastResult forecastResult = JsonUtils.getGson().fromJson(resJson, new TypeToken<AiForecastResult>() {
        }.getType());
        return forecastResult;
    }

    public AiForecastResult getForecastResultByYuanQi(List<ForecastQaItemDto> qaList, Long userId) throws CommonException {
        String prompt = forecastPrompt
                .replace("{{question}}", ForecastQaItemDto.toQuestionPrompt(qaList))
                .replace("{{answer}}", ForecastQaItemDto.toAnswerPrompt(qaList));

        List<YuanQiChatCompletionsReq.Message> messagesList = new ArrayList<>();
        messagesList.add(new YuanQiChatCompletionsReq.Message()
                .setRole("user")
                .setContent(Collections.singletonList(new YuanQiChatCompletionsReq.Message.ContentItem()
                        .setType("text")
                        .setText(prompt)))
        );
        String resJson = yuanQiManager.chatJson(messagesList, String.valueOf(userId));
        if (resJson != null && resJson.contains("code:429") && resJson.contains("Too Many Requests")) {
            CommonException.throwException("服务器繁忙，请再试一次");
        }

        log.info("【AI 预测结果】请求:" + prompt + "\n返回:" + resJson);

        AiForecastResult forecastResult = JsonUtils.getGson().fromJson(resJson, new TypeToken<AiForecastResult>() {
        }.getType());
        return forecastResult;
    }


    public void chat(List<Chat.ChatContentItem> chatContentList, String userId, ChatFluxListener listener) {
        List<YuanQiChatCompletionsReq.Message> messagesList = new ArrayList<>();

        for (Chat.ChatContentItem item : chatContentList) {
            YuanQiChatCompletionsReq.Message message = new YuanQiChatCompletionsReq.Message()
                    .setRole(item.getRole())
                    .setContent(Collections.singletonList(new YuanQiChatCompletionsReq.Message.ContentItem()
                            .setType("text")
                            .setText(item.getContent())));
            messagesList.add(message);
        }
        log.info("Chat yuanQiManager.chatFlux()");
        yuanQiManager.chatFlux(messagesList, userId, listener);
    }

}
